﻿using System;
using System.Security.Cryptography;
using System.Windows.Media.Imaging;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Windows.Media;
using System.Drawing.Imaging;
using Shoozla.DataModel.Helper;

namespace Shoozla.DataModel
{

    /// <summary>
    /// Class to display a preview of the artwork, selectable
    /// </summary>
    public class CoverThumb : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public SearchMethod Method { get; set; } //to store the method used to find it
        public String DisplayString { get; set; }
        public Uri CachedUrl { get; set; }
        private bool _isSelected;
        public bool IsSelected
        {
            get { return _isSelected; }
            set
            {
                _isSelected = value;
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs("IsSelected"));
            }
        }

        public CoverThumb(String display, Uri cachedUrl, SearchMethod method)
        {
            Method = method;
            DisplayString = display;
            CachedUrl = cachedUrl;
            IsSelected = false;
        }
    }

    /// <summary>
    /// Class to display a preview of the artwork, selectable
    /// </summary>
    //public class CoverThumb : INotifyPropertyChanged
    //{
    //    public event PropertyChangedEventHandler PropertyChanged;

    //    public String DisplayString { get; set; }
    //    public String CachedUrl { get; set; }

    //    BitmapImage 
    //    BitmapImage Preview { get; 
    //        set 
            
    //         if (PropertyChanged != null)
    //                PropertyChanged(this, new PropertyChangedEventArgs("IsSelected"));
    //    }

    //    private bool _isSelected;
    //    public bool IsSelected
    //    {
    //        get { return _isSelected; }
    //        set
    //        {
    //            _isSelected = value;
    //            if (PropertyChanged != null)
    //                PropertyChanged(this, new PropertyChangedEventArgs("IsSelected"));
    //        }
    //    }

    //    public CoverThumb(String display, String cachedUrl, Image cover)
    //    {
    //        Preview = ImageHelper.ImageToBitmapImage(cover); //resize the image to save memory space
    //        DisplayString = display;
    //        CachedUrl = cachedUrl;
    //        IsSelected = false;
    //    }
    //}

    public class Mp3File : INotifyPropertyChanged, IComparable
    {
        private BitmapSource _coverThumb; //to save memory, resized
        private String _artist;
        private String _albumName;
        private String _title;
        private String _genre;
        private String _year;
        private Image _cover;
        private FileInfo _filename;
        private String _hash;
        private bool _dirty;
        private bool _isSelected;

        private Uri _uri;
        public event PropertyChangedEventHandler PropertyChanged;

        public Mp3File(FileInfo filename) { FileName = filename; /*ComputeHash();*/ Dirty = false; IsSelected = false; }
        public Mp3File() { }

        public override string ToString()
        {
            return String.Format("{0} - {1} ({2}) - Cover: {3}", Artist, Title, AlbumName, HasCover);
        }

        private void ComputeHash()
        {
            Hash = String.Empty;

            //if (FileName != null)
            //{
            //    MD5 alg = MD5Cng.Create();
            //    byte[] hash = alg.ComputeHash(System.Text.Encoding.ASCII.GetBytes(FileName.FullName.Trim()));
            //    string hashed = "";
            //    for (int i = 0; i < hash.Length; i++)
            //        hashed += hash[i].ToString();
            //    Hash = hashed;
            //}
            //else
            //    Hash = String.Empty;
        }

        #region Properties

        public String ShortName //not updating itself --> not use for realtime binding
        {
            get { return Artist + " - " + Title; }
        }
      

        public String Hash
        {
            get { return _hash; }
            private set { _hash = value; }
        }

        public String Artist
        {
            get
            {
                if (_artist == null)
                    _artist = String.Empty;
                return _artist;
            }
            set
            {
                if (!String.IsNullOrEmpty(value))
                {
                    _artist = value;
                    OnPropertyChanged("Artist");
                }
            }
        }

        public String AlbumName
        {
            get
            {
                if (_albumName == null)
                    _albumName = String.Empty;
                return _albumName;
            }
            set
            {
                    _albumName = value; 
                    OnPropertyChanged("AlbumName");
            }
        }

        public String Genre
        {
            get
            {
                if (_genre == null)
                    _genre = String.Empty;
                return _genre;
            }
            set
            {
                    _genre = value;
                    OnPropertyChanged("Genre");
            }
        }

        public String Year
        {
            get
            {
                if (_year == null)
                    _year = String.Empty;
                return _year;
            }
            set
            {
                    _year = value;
                    OnPropertyChanged("Year");
            }
        }

        public String Title
        {
            get
            {
                if (_title == null)
                    _title = String.Empty;
                return _title;
            }
            set
            {
                if (!String.IsNullOrEmpty(value))
                {
                    _title = value;
                    OnPropertyChanged("Title");
                }
            }
        }

        public Image Cover
        {
            get
            {
                return _cover;
            }
            set
            {
                if (value != null)
                {
                    _cover = value;
                    _coverThumb = null;
                    Dirty = true;
                    HasCover = true;
                    OnPropertyChanged("Cover");
                    OnPropertyChanged("ImageBitmap");
                    OnPropertyChanged("HasCover"); 
                }
            }
        }

        private bool DummyDelegate() { return true; }

        public BitmapSource ImageBitmap
        {
            get
            {
                if(_coverThumb == null && _cover != null)
                    _coverThumb = ImageHelper.ImageToBitmapImage(_cover);
                return _coverThumb;
            }
        }

        public Uri ImageUrl
        {
            get
            {
                return _uri;
            }
            set
            {
                _uri = value;
                OnPropertyChanged("ImageUrl");
            }
        }

        public bool IsSelected
        {
            get
            {
                return _isSelected;
            }
            set
            {
                if (_isSelected != value)
                {
                    _isSelected = value;
                    OnPropertyChanged("IsSelected");
                }
            }
        }

        public FileInfo FileName
        {
            get
            {
                return _filename;
            }
            set
            {
                if (value !=null)
                {
                    _filename = value;
                    ComputeHash();
                    OnPropertyChanged("FileName"); 
                }
            }
        }

        public bool HasCover { get; set; }
 
        public bool Dirty
        {
            get
            {
                return _dirty;
            }
            set
            {
                if (_dirty != value)
                {
                    _dirty = value;
                    OnPropertyChanged("Dirty");
                }
            }
        }

        void OnPropertyChanged(string propname)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propname));
                if (propname != "Dirty" && propname != "IsSelected" && propname != "ImageUrl")
                     Dirty = true;
            }
        }

        #endregion

        /// <summary>
        /// Copy all the tags from one the source Mp3 to the target Mp3, do not save it, only a memory copy
        /// </summary>
        /// <param name="source">Mp3 to copy</param>
        /// <param name="target">Mp3 to fill</param>
        public static void CloneMp3(Mp3File source, ref Mp3File target)
        {          
            target.AlbumName = source.AlbumName;
            target.Cover = source.Cover;
            target.Dirty = source.Dirty;
            target.Artist = source.Artist;
            target.Title = source.Title;
            target.Year = source.Year;
            target.Genre = source.Genre;
            target.FileName = source.FileName;
            target.ImageUrl = source.ImageUrl;
            target.IsSelected = source.IsSelected;
        }

        //public static readonly DependencyProperty ItemProperty = DependencyProperty.Register(
        //  "Dirty", typeof(bool), typeof(Mp3File), new PropertyMetadata(new Boolean()));


        // Returns:
        //     A value that indicates the relative order of the objects being compared.
        //     The return value has these meanings: Value Meaning Less than zero This instance
        //     is less than obj. Zero This instance is equal to obj. Greater than zero This
        //     instance is greater than obj.
        //
        // Exceptions:
        //   System.ArgumentException:
        //     obj is not the same type as this instance.
        public int CompareTo(object obj)
        {
            if (obj is Mp3File)
            {
                Mp3File m = (Mp3File)obj;
                if(m.FileName.FullName == this.FileName.FullName)
                    return 0;
                else
                    return -1;
            }
            else
                throw new ArgumentException("Not a Mp3File");
        }

    }

    //public class Cover : INotifyPropertyChanged
    //{
    //    public event PropertyChangedEventHandler PropertyChanged;

    //    private Uri _uri;
    //    private bool _dirty;
    //    private Image _im;

    //    public Uri URI
    //    {
    //        get
    //        {
    //            return _uri;
    //        }
    //        set
    //        {
    //            if (value != null)
    //            {
    //                _uri = value;
    //            }
    //        }
    //    }
    //    public bool Dirty
    //    {
    //        get
    //        {
    //            return _dirty;
    //        }
    //        set
    //        {
    //            if (_dirty != value)
    //            {
    //                _dirty = value;
    //                OnPropertyChanged("Dirty");
    //            }
    //        }
    //    }
    //    public Image Image
    //    {
    //        get { return _im; }
    //        set
    //        {
    //            if (value != null)
    //            {
    //                _im = value;
    //                OnPropertyChanged("Image");
    //            }
    //        }
    //    }

    //    public BitmapImage ImageBitmap
    //    {
    //        get { return ImageHelper.ImageToBitmapImage((Image)_im.Clone()); }
    //    }

    //    public string FileName { get; set; }

    //    public Cover(Uri uri, string filename) { URI = uri; FileName = filename; Dirty = true; }
    //    public Cover(string filename) { FileName = filename; Dirty = true; }
    //    public Cover(Image im, string filename) { Image = im; FileName = filename; Dirty = true; }

    //    public override string ToString()
    //    {
    //        return "Cover: " + URI;
    //    }

    //    void OnPropertyChanged(string propname)
    //    {
    //        if (PropertyChanged != null)
    //        {
    //            PropertyChanged(this, new
    //                PropertyChangedEventArgs(propname));
    //            if (propname != "Dirty")
    //                Dirty = true;
    //        }
    //    }

    //}

}
